package mirkofrancuski.battleship.gui;

import java.util.Arrays;
import java.util.HashSet;

import mirkofrancuski.battleship.R;
import mirkofrancuski.battleship.game.Board;
import mirkofrancuski.battleship.game.Board.Direction;
import mirkofrancuski.battleship.game.Cell;
import mirkofrancuski.battleship.game.Coordinates;
import mirkofrancuski.battleship.game.Ship;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;

public class GameBoard extends View {
	private String DEBUG_TAG = "DEBUG GameBoard";

	protected final DrawableShip[] mShips = {
			new DrawableShip(this, Cell.AIRCRAFT_CARRIER),
			new DrawableShip(this, Cell.BATTLESHIP),
			new DrawableShip(this, Cell.SUBMARINE),
			new DrawableShip(this, Cell.CRUISER),
			new DrawableShip(this, Cell.DESTROYER) };

	protected Board board;

	protected Point mStartPoint;
	protected int mCellWidth;

	protected boolean mMainBoard;

	protected Coordinates touchCoordinates;

	public GameBoard(Context context) {
		this(context, null);
	}

	public GameBoard(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public GameBoard(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		if (!isInEditMode()) {

			WindowManager wm = (WindowManager) getContext().getSystemService(
					Context.WINDOW_SERVICE);
			Display display = wm.getDefaultDisplay();
			int gameBoardSize = display.getWidth();

			mCellWidth = gameBoardSize / 12;

		} else
			mCellWidth = this.getWidth() / 12;

		TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
				R.styleable.GameBoard, 0, 0);

		try {
			mMainBoard = a.getBoolean(R.styleable.GameBoard_main_board, true);
		} finally {
			a.recycle();
		}

		if (!mMainBoard)
			mCellWidth /= 2;

		mStartPoint = new Point(mCellWidth + mCellWidth / 4, mCellWidth
				+ mCellWidth / 4);

		touchCoordinates = new Coordinates(-1, -1);

		Resources res = this.getResources();
		for (DrawableShip ship : mShips) {
			ship.setBitmaps(res, mCellWidth);
		}
		this.board = new Board();

	}

	public void setBoard(Board board) {
		this.board = board;
		setShips();
		invalidate();
	}

	public Board getBoard() {
		return board;
	}

	protected void setShips() {
//		HashSet<Cell> unselectedShips = new HashSet<Cell>(
//				Arrays.asList(Board.ships));
//
//		Cell cell;
//		Coordinates coord = new Coordinates();
//
//		for (int i = 0; i < Board.BOARD_SIZE; i++)
//			for (int j = 0; j < Board.BOARD_SIZE; j++) {
//				cell = board.getCell(i, j);
//				if (unselectedShips.contains(cell)) {
//					coord.horizontal = i;
//					coord.vertical = j;
//					
//					setShip(coord, cell);
//
//					unselectedShips.remove(cell);
//					if (unselectedShips.isEmpty())
//						return;
//				}
//			}
		
		for(Cell shipCell: Board.ships){
			Ship ship = board.selectPlacedShip(shipCell);
			if(ship == null)
				continue;			
			
			setShip(ship.start,shipCell);
		}
		
		
	}

	private void setShip(Coordinates coord, Cell cell) {
		if(cell == Cell.MISS || cell == Cell.HIT || cell == Cell.EMPTY)
			return;
		
		Direction direction = board.getShipDirection(coord, cell);
		coord = board.getShipBegining(coord, direction, cell);

		DrawableShip dShip = selectDrawableShip(cell);
		if (direction != dShip.ship.direction)
			dShip.rotate();
		dShip.setBegining(coord);
		dShip.place();
	}

	public Point getStartPoint() {
		return mStartPoint;
	}

	public int getCellWidth() {
		return mCellWidth;
	}

	protected DrawableShip selectDrawableShip(Cell ship) {
		switch (ship) {
		case AIRCRAFT_CARRIER:
			return mShips[0];
		case BATTLESHIP:
			return mShips[1];
		case SUBMARINE:
			return mShips[2];
		case CRUISER:
			return mShips[3];
		case DESTROYER:
			return mShips[4];
		default:
			break;
		}
		return null;
	}

	protected int calcX(int column) {
		return mStartPoint.x + column * mCellWidth;
	}

	protected int calcY(int row) {
		return mStartPoint.y + row * mCellWidth;
	}

	protected Coordinates calcCoord(int x, int y) {
		touchCoordinates.horizontal = (y - mStartPoint.y) / mCellWidth;
		touchCoordinates.vertical = (x - mStartPoint.x) / mCellWidth;

		return touchCoordinates;
	}

	protected Coordinates calcCoord(float x, float y) {
		touchCoordinates.horizontal = (Math.round(y) - mStartPoint.y)
				/ mCellWidth;
		touchCoordinates.vertical = (Math.round(x) - mStartPoint.x)
				/ mCellWidth;

		return touchCoordinates;
	}

}
